﻿package com.sohu.sns.avatar {
	import com.sohu.utils.BasicGemo;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;

	public class EditWindow extends Sprite {
		private var maskBlock : Sprite;
		// private var orignScale : Number;
		private var orignBoxHeight : Number;
		// private var cameroVideo : Video;
		private var wWidth : Number;
		private var snapHeight : Number;
		private var snapWidth : Number;
		private var thumbData : BitmapData;
		private var thumbText : TextField;
		// private var camera : Camera;
		private var thumbWin : PhotoThumb;
		private var orignBoxWidth : Number;
		// private var loadMode : Boolean = true;
		private var photoBitMapData : BitmapData;
		private var photoSp : Sprite;
		private var scalN : Number;
		// private var pPath : String;
		private var pWidth : Number;
		private var pHeight : Number;
		private var dragRect : Rectangle;
//		private var range : Number;
		private var photoMask : Sprite;
		private var alphaBg : Sprite;
		private var scaleP : Number = 1;
		private var boxH : Number;
		// private var snapSize : Number = 48;
		// private var photoLoader : Loader;
		private var boxX : Number;
		private var boxY : Number;
		private var photoContainer : Sprite;
		private var maskContainer : Sprite;
		private var dragBox : DragBox;
		private var boxW : Number;
		private var wHeight : Number;
		public static var SNAP : String = "snap";

		public function EditWindow(photoBitMapData : BitmapData = null, width : Number = 300, height : Number = 300, originBoxWidth : Number = 165, orignBoxHeight : Number = 200) {
			thumbWin = new PhotoThumb(80, 80);
			thumbText = new TextField();
			this.photoBitMapData = photoBitMapData;
			this.wWidth = width;
			this.wHeight = height;
			this.orignBoxWidth = originBoxWidth;
			this.orignBoxHeight = orignBoxHeight;
			this.addEventListener(Event.ADDED_TO_STAGE, onStage);
		}

		// private function onResize(event : Event) : void {
		// this.adjustMask();
		// this.movePhoto();
		// }
		private function snapp() : void {
			var fromX : Number = this.dragBox.x - this.photoSp.x;
			var fromY : Number = this.dragBox.y - this.photoSp.y;
			var selectedRange : Rectangle = new Rectangle(fromX, fromY, this.dragBox.box.width, this.dragBox.box.height);
			var thumbMatrix : Matrix = new Matrix();
			var scalaWidth : Number = this.snapWidth / this.dragBox.box.width;
			var scalaHeight : Number = this.snapHeight / this.dragBox.box.height;
			thumbMatrix.scale(scalaWidth, scalaHeight);
			var smoothing : Boolean = true;
			if (scalaWidth >= 0.98 && scalaWidth <= 1) {
				thumbMatrix = null;
				smoothing = false;
			} else {
				smoothing = true;
			}
			var selectedPhoto : BitmapData = new BitmapData(this.dragBox.box.width, this.dragBox.box.height);
			var sourcePhoto : BitmapData = new BitmapData(this.photoSp.width, this.photoSp.height);
			var sourceMatrix : Matrix = new Matrix();
			sourceMatrix.scale(this.scaleP, this.scaleP);
			sourcePhoto.draw(this.photoSp, sourceMatrix, null, null, null, smoothing);
			selectedPhoto.copyPixels(sourcePhoto, selectedRange, new Point(0, 0));
			this.thumbData = new BitmapData(this.snapWidth, this.snapHeight);
			this.thumbData.draw(selectedPhoto, thumbMatrix, null, null, null, smoothing);
			selectedPhoto.dispose();
			sourcePhoto.dispose();
			this.dispatchEvent(new Event(SNAP));
		}

		private function init() : void {
			this.photoContainer = new Sprite();
			this.photoContainer = BasicGemo.drawRectSprite(this.wWidth, this.wHeight, 0xFFFFFF, 0);
			addChild(this.photoContainer);
			this.photoSp = new Sprite();
			this.photoContainer.addChild(this.photoSp);
			
			this.photoMask = new Sprite();
			this.photoMask = BasicGemo.drawRectSprite(this.wWidth, this.wHeight);
			addChild(this.photoMask);
			this.photoContainer.mask = this.photoMask;
			
			this.maskContainer = new Sprite();
			this.maskContainer.blendMode = BlendMode.LAYER;
			addChild(this.maskContainer);
			
			this.alphaBg = BasicGemo.drawRectSprite(this.wWidth, this.wHeight, 0, 0.6);
			this.maskBlock = BasicGemo.drawRectSprite(100, 100, 0);
			this.maskBlock.blendMode = BlendMode.ERASE;
			this.maskContainer.addChild(this.alphaBg);
			this.maskContainer.addChild(this.maskBlock);
			
			this.centerObj(this.photoSp);
			this.centerObj(this.photoMask);
			this.centerObj(this.maskBlock);
		}

		public function edit(editData : BitmapData, snapWidth : Number = 165, snapHeight : Number = 200) : void {
			//对齐位置
			this.snapWidth = snapWidth;
			this.snapHeight = snapHeight;
			//图片以及尺寸
			this.photoBitMapData = editData;
			this.pWidth = this.photoBitMapData.width;
			this.pHeight = this.photoBitMapData.height;
			//移除所有子对象
			while (this.photoSp.numChildren) {
				this.photoSp.removeChildAt(0);
			}
			//显示待编辑图片
			var originBitmap : Bitmap = new Bitmap(this.photoBitMapData, PixelSnapping.NEVER, true);
			this.photoSp.addChild(originBitmap);
			trace('photoBitMapData.width: ' + (this.photoBitMapData.width) + ' photoBitMapData.height: ' + (this.photoBitMapData.height));
			trace('photoSp.parent: ' + (photoSp.parent));
			//照片相关显示对象居中
			this.centerObj(this.photoSp);
			this.centerObj(this.photoMask);
			this.centerObj(this.maskBlock);
			//调整边界
			this.adjustBoundary(this.photoSp.width, this.photoSp.height);
			//选取区域
			addChild(this.dragBox);
			if (this.dragBox.width > this.pWidth || this.dragBox.height > this.pHeight) {
				var minSize : Number = this.pWidth > this.pHeight ? (this.pHeight) : (this.pWidth);
				this.dragBox.resize(minSize);
				this.orignBoxWidth = this.dragBox.width;
				this.orignBoxHeight = this.dragBox.height;
			}
			this.centerObj(this.dragBox);
			//调整这招
			this.adjustMask();
			//监听选取区域
			this.dragBox.addEventListener(DragBox.START_RESIZE, onResizeStart);
			this.dragBox.addEventListener(DragBox.START_MOVE, onMoveStart);
			this.dragBox.addEventListener(DragBox.STOPMOVE, onMoveStop);
			this.snapp();
		}

		public function get scaleRange() : Number {
			var minLength : Number = this.pWidth < this.pHeight ? (this.pWidth) : (this.pHeight);
			var scaleRange : Number = minLength / this.dragBox.maxLength;
			return scaleRange - 1;
		}

		public function forceScale(scala : Number) : void {
			this.scalN = scala;
			var _loc_2 : Number = 1 / (this.scaleRange + 1);
			this.scaleP = _loc_2 + (1 - _loc_2) * scala;
			if (this.scaleP > 1) {
				this.scaleP = 1;
			}
			this.photoSp.scaleY = this.scaleP;
			this.photoSp.scaleX =  this.scaleP;
			if (this.photoSp.width <= this.wWidth) {
				this.photoSp.x = -Math.ceil((this.photoSp.width - this.wWidth) / 2);
			}
			if (this.photoSp.height <= this.wHeight) {
				this.photoSp.y = -Math.ceil((this.photoSp.height - this.wHeight) / 2);
			}
			this.adjustBoundary(this.photoSp.width, this.photoSp.height);
			this.centerObj(this.dragBox);
			this.dragBox.resume(this.orignBoxWidth, this.orignBoxHeight);
			this.adjustMask();
			this.movePhoto();
		}

		private function onMouseMove(event : MouseEvent) : void {
			this.adjustMask();
			this.movePhoto();
		}

		private function adjustMask() : void {
			this.maskBlock.x = this.dragBox.x;
			this.maskBlock.y = this.dragBox.y;
			this.maskBlock.width = this.dragBox.box.width;
			this.maskBlock.height = this.dragBox.box.height;
		}

		public function get thumbBmpData() : BitmapData {
			return this.thumbData;
		}

		public function setSnapp() : void {
			this.snapp();
		}
		
		/**
		 * 设置图片比例
		 */
		public function setPhotoScale(scala : Number) : void {
			this.scalN = scala;
			var _loc_2 : Number = 1 / (this.scaleRange + 1);
			this.scaleP = _loc_2 + (1 - _loc_2) * scala;
			this.photoSp.scaleY = this.scaleP;
			this.photoSp.scaleX = this.scaleP;
			this.movePhoto();
			if (this.photoSp.width <= this.wWidth) {
				this.photoSp.x = -Math.ceil((this.photoSp.width - this.wWidth) / 2);
			}
			if (this.photoSp.height <= this.wHeight) {
				this.photoSp.y = -Math.ceil((this.photoSp.height - this.wHeight) / 2);
			}
			this.adjustBoundary(this.photoSp.width, this.photoSp.height);
			this.dragBox.x = this.dragBox.x > this.photoSp.x ? (this.dragBox.x) : (this.photoSp.x);
			this.dragBox.y = this.dragBox.y > this.photoSp.y ? (this.dragBox.y) : (this.photoSp.y);
			var maxLength : Number = this.dragBox.width > this.dragBox.height ? (this.dragBox.width) : (this.dragBox.height);
			var minLength : Number = this.photoSp.width > this.photoSp.height ? (this.photoSp.height) : (this.photoSp.width);
			if (this.dragBox.x + this.dragBox.width > this.photoSp.x + this.photoSp.width) {
				if (maxLength > minLength) {
					this.dragBox.resize(minLength);
				}
				this.dragBox.x = this.photoSp.x + this.photoSp.width - this.dragBox.width;
			}
			if (this.dragBox.y + this.dragBox.height > this.photoSp.y + this.photoSp.height) {
				if (maxLength > minLength) {
					this.dragBox.resize(minLength);
				}
				this.dragBox.y = this.photoSp.y + this.photoSp.height - this.dragBox.height;
			}
			this.adjustMask();
		}

		private function onResizeStart(event : Event) : void {
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}

		public function get scalePercent() : Number {
			return this.scalN;
		}

		public function get fullBmpData() : BitmapData {
			return this.photoBitMapData;
		}

		// private function adjustPostion(param1 : Object) : void {
		// param1.x = -Math.ceil((param1.width - (this.dragBox.x + this.dragBox.width / 2)) / 2);
		// param1.y = -Math.ceil((param1.height - (this.dragBox.y + this.dragBox.height / 2)) / 2);
		// }
		private function onStage(event : Event) : void {
			this.removeEventListener(Event.ADDED_TO_STAGE, onStage);
			this.init();
		}

		private function adjustBoundary(inWidth : Number, inHeight : Number) : void {
			var x : Number = 0;
			var y : Number = 0;
			var width : Number = this.wWidth;
			var height : Number = this.wHeight;
			if (inWidth >= this.wWidth) {
				x = 0;
				width = this.wWidth;
			} else {
				x = this.photoSp.x;
				width = this.photoSp.width;
			}
			if (inHeight >= this.wHeight) {
				y = 0;
				height = this.wHeight;
			} else {
				y = this.photoSp.y;
				height = this.photoSp.height;
			}
			this.dragRect = new Rectangle(x, y, width, height);
			if (!this.dragBox) {
				this.dragBox = new DragBox(this.dragRect, this.orignBoxWidth, this.orignBoxHeight);
			} else {
				this.dragBox.resetBoundary(this.dragRect);
			}
		}
		
		/**
		 * 根据选取区域比例移动原始图片
		 */
		private function movePhoto() : void {
			this.boxX = this.dragBox.x;
			this.boxY = this.dragBox.y;
			this.boxW = this.dragBox.box.width;
			this.boxH = this.dragBox.box.height;
			var scalaX : Number = (boxX - this.dragRect.x) / (this.dragRect.width - boxW);
			var scalaY : Number = (boxY - this.dragRect.y) / (this.dragRect.height - boxH);
			scalaX = Math.max(0, scalaX);
			scalaX = Math.min(1, scalaX);
			scalaY = Math.max(0, scalaY);
			scalaY = Math.min(1, scalaY);
			this.photoSp.x = boxX - (this.photoSp.width - boxW) * scalaX;
			this.photoSp.y = boxY - (this.photoSp.height - boxH) * scalaY;
		}
		
		/**
		 * 居中显示
		 */
		private function centerObj(target : DisplayObject) : void {
			target.x = -Math.ceil((target.width - this.wWidth) / 2);
			target.y = -Math.ceil((target.height - this.wHeight) / 2);
		}

		// private function onBoxMove(event : Event) : void {
		// this.adjustMask();
		// this.movePhoto();
		// }
		public function reset(scala : Number = 1) : void {
			this.dragBox.resume(this.orignBoxWidth, this.orignBoxHeight);
			this.centerObj(this.dragBox);
			this.setPhotoScale(scala);
			this.adjustMask();
			this.movePhoto();
			this.snapp();
		}

		private function onMoveStart(event : Event) : void {
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}

		private function onMoveStop(event : Event) : void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			this.adjustMask();
			this.movePhoto();
			this.snapp();
		}
	}
}
